package com.qingfeng.medical.controller.admin.auth;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.qingfeng.medical.base.controller.BaseController;
import com.qingfeng.medical.base.handler.GeneralAuthException;
import com.qingfeng.medical.base.log.annotation.Log;
import com.qingfeng.medical.base.log.enums.BusinessType;
import com.qingfeng.medical.base.result.Result;
import com.qingfeng.medical.base.result.ResultCodeEnum;
import com.qingfeng.medical.biz.auth.domain.dto.AssginRoleDTO;
import com.qingfeng.medical.biz.auth.domain.dto.SysRoleQueryDTO;
import com.qingfeng.medical.biz.auth.domain.entity.SysRole;
import com.qingfeng.medical.biz.auth.service.SysRoleService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Map;


/**
 * 角色管理控制层
 *
 * @author 清风学Java
 * @version 1.0.0
 * @date 2023/4/2
 */
@Api(tags = "角色管理")
@RestController
@RequestMapping("/admin/system/sysRole")
public class SysRoleController extends BaseController {

    @Autowired
    private SysRoleService sysRoleService;

    @Log(title = "角色管理", businessType = BusinessType.SELECT, message = "获取角色分页列表")
    @PreAuthorize("hasAuthority('bnt.sysRole.list')")
    @ApiOperation(value = "获取角色分页列表", notes = "获取角色的分页列表")
    @GetMapping("/{page}/{limit}")
    public Result<IPage<SysRole>> index(
            @ApiParam(name = "page", value = "当前页码", required = true)
            @PathVariable Long page,
            @ApiParam(name = "limit", value = "每页记录数", required = true)
            @PathVariable Long limit,
            @ApiParam(name = "roleQueryVo", value = "查询对象", required = false)
                    SysRoleQueryDTO roleQueryDTO) {
        IPage<SysRole> pageModel = sysRoleService.selectPage(
                new Page<SysRole>(page, limit),
                roleQueryDTO
        );
        return Result.ok(pageModel);
    }

    @Log(title = "角色管理", businessType = BusinessType.SELECT, message = "根据Id获取角色信息")
    @PreAuthorize("hasAuthority('bnt.sysRole.list')")
    @ApiOperation(value = "根据Id获取角色信息", notes = "根据Id获取角色信息")
    @GetMapping("/get/{id}")
    public Result<SysRole> get(@PathVariable Long id) {
        SysRole role = sysRoleService.getById(id);
        return Result.ok(role);
    }

    @Log(title = "角色管理", businessType = BusinessType.INSERT, message = "新增角色信息")
    @PreAuthorize("hasAuthority('bnt.sysRole.add')")
    @ApiOperation(value = "新增角色", notes = "新增角色")
    @PostMapping("/save")
    public Result save(@RequestBody SysRole role) {
        checkRole(role);

        sysRoleService.save(role);
        return Result.ok();
    }

    @Log(title = "角色管理", businessType = BusinessType.UPDATE, message = "修改角色信息")
    @PreAuthorize("hasAuthority('bnt.sysRole.update')")
    @ApiOperation(value = "修改角色信息", notes = "修改角色信息")
    @PutMapping("/update")
    public Result updateById(@RequestBody SysRole role) {
        checkRole(role);
        sysRoleService.updateById(role);
        return Result.ok();
    }

    @Log(title = "角色管理", businessType = BusinessType.DELETE, message = "根据Id删除角色")
    @PreAuthorize("hasAuthority('bnt.sysRole.remove')")
    @ApiOperation(value = "根据Id删除角色", notes = "根据Id删除角色")
    @DeleteMapping("/remove/{id}")
    public Result remove(@PathVariable Long id) {
        sysRoleService.removeByRoleId(id);
        return Result.ok();
    }

    @Log(title = "角色管理", businessType = BusinessType.DELETE, message = "根据id批量删除角色")
    @PreAuthorize("hasAuthority('bnt.sysRole.remove')")
    @ApiOperation(value = "根据id批量删除角色", notes = "根据id批量删除角色")
    @DeleteMapping("/batchRemove")
    public Result batchRemove(@RequestBody List<Long> idList) {
        sysRoleService.removeRoleByIds(idList);
        return Result.ok();
    }

    @Log(title = "角色管理", businessType = BusinessType.SELECT, message = "根据用户Id获取角色数据")
    @PreAuthorize("hasAuthority('bnt.sysUser.assignRole')")
    @ApiOperation(value = "根据用户Id获取角色数据", notes = "根据用户Id获取角色数据")
    @GetMapping("/toAssign/{userId}")
    public Result toAssign(@PathVariable Long userId) {
        Map<String, Object> roleMap = sysRoleService.getRolesByUserId(userId);
        return Result.ok(roleMap);
    }

    @Log(title = "角色管理", businessType = BusinessType.ASSGIN, message = "根据用户分配角色")
    @PreAuthorize("hasAuthority('bnt.sysUser.assignRole')")
    @ApiOperation(value = "根据用户分配角色", notes = "根据用户分配角色")
    @PostMapping("/doAssign")
    public Result doAssign(@RequestBody AssginRoleDTO assginRoleDTO) {
        sysRoleService.doAssign(assginRoleDTO);
        return Result.ok();
    }

    private void checkRole(SysRole role) {
        // 角色编码不能重复
        List<SysRole> sysRoleList = sysRoleService.list(
                new LambdaQueryWrapper<SysRole>()
                        .eq(SysRole::getRoleCode, role.getRoleCode())
        );
        if (CollUtil.isNotEmpty(sysRoleList)) {
            throw new GeneralAuthException(ResultCodeEnum.FAIL.getCode(), "角色编码重复");
        }
    }
}
